<template>
  <div id="decrypt">
    <el-container>
      <el-header>文件解密工具</el-header>
      <el-main>
        <el-upload
            class="upload-demo"
            drag
            action="#"
            :on-change="handleFileChange"
            :auto-upload="false"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将加密文件拖到此处，或<em>点击上传</em></div>
        </el-upload>

        <el-select v-model="algorithm" placeholder="请选择加密算法">
          <el-option label="AES" value="AES"></el-option>
          <el-option label="DES" value="DES"></el-option>
          <el-option label="3DES" value="3DES"></el-option>
          <el-option label="SM4" value="SM4"></el-option>
        </el-select>

        <el-input
            v-model="key"
            placeholder="请输入密钥"
        ></el-input>

        <el-input
            v-if="algorithm === 'SM4'"
            v-model="iv"
            placeholder="请输入初始化向量 (IV)"></el-input
        >

        <el-button @click="decryptFile" type="primary">解密文件</el-button>

        <p v-if="decryptedData">解密后的数据已自动下载</p>

      </el-main>
    </el-container>
  </div>
</template>

<script>
import CryptoJS from 'crypto-js';
import SM4 from 'sm-crypto';

export default {
  name: 'Decrypt',
  data() {
    return {
      file: null,
      algorithm: this.$route.query.algorithm || 'AES',
      key: this.$route.query.key || '',
      iv: this.$route.query.iv || '', // 初始化向量
      decryptedData: ''
    };
  },
  methods: {
    handleFileChange(file) {
      this.file = file.raw;
    },
    decryptFile() {
      if (!this.file || !this.key) {
        alert('请选择文件并填写或生成密钥');
        return;
      }

      const reader = new FileReader();
      reader.onload = (event) => {
        const content = event.target.result;
        const lines = content.split('\n');
        let metadata;
        let encryptedData;

        try {
          metadata = JSON.parse(lines[0]);
          encryptedData = lines.slice(1).join('\n');
        } catch (e) {
          console.error('Failed to parse metadata:', e);
          metadata = {};
          encryptedData = content;
        }

        let userKey = this.key;
        let userIv = this.iv;

        if (metadata.key && metadata.iv) {
          userIv = metadata.iv;
        }

        let decrypted;

        switch (this.algorithm) {
          case 'AES':
            decrypted = CryptoJS.AES.decrypt(encryptedData, userKey, { iv: CryptoJS.enc.Hex.parse(userIv) }).toString(CryptoJS.enc.Latin1);
            break;
          case 'DES':
            decrypted = CryptoJS.DES.decrypt(encryptedData, userKey, { iv: CryptoJS.enc.Hex.parse(userIv) }).toString(CryptoJS.enc.Latin1);
            break;
          case '3DES':
            decrypted = CryptoJS.TripleDES.decrypt(encryptedData, userKey, { iv: CryptoJS.enc.Hex.parse(userIv) }).toString(CryptoJS.enc.Latin1);
            break;
          case 'SM4':
            const sm4Key = userKey.slice(0, 32); // Ensure key length is 16 bytes for SM4
            const sm4Iv = userIv.slice(0, 32); // Ensure IV length is 16 bytes for SM4
            decrypted = SM4.sm4.decrypt(encryptedData, sm4Key, { mode: 'cbc', iv: sm4Iv });
            break;
          default:
            decrypted = '';
        }

        this.decryptedData = decrypted;
        this.downloadDecryptedFile(decrypted);
      };

      reader.readAsText(this.file);
    },
    downloadDecryptedFile(data) {
      const originalFileName = this.file.name.replace(/\.enc$/, '');
      const fileNameParts = originalFileName.split('.');
      const baseName = fileNameParts.slice(0, -1).join('.');
      const extension = fileNameParts[fileNameParts.length - 1];
      let version = 1;
      let newFileName = `${baseName} (${version}).${extension}`;

      while (localStorage.getItem(newFileName)) {
        version++;
        newFileName = `${baseName} (${version}).${extension}`;
      }

      localStorage.setItem(newFileName, 'exists');

      const byteArray = new Uint8Array(data.length);
      for (let i = 0; i < data.length; i++) {
        byteArray[i] = data.charCodeAt(i) & 0xff;
      }
      const blob = new Blob([byteArray], { type: 'application/octet-stream' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = newFileName;
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.URL.revokeObjectURL(url);
    }
  }
};
</script>

<style scoped>
#decrypt {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.upload-demo {
  margin-bottom: 20px;
}
</style>



